package com.android.dx.ppx.app;

import android.content.Context;
import android.support.annotation.Keep;
import android.support.multidex.MultiDex;
import android.util.Log;

import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixApplication;
import com.taobao.sophix.SophixEntry;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;

/**
 * Author: Ligang
 * Date: 2019/09/16
 * Description: 新的初始化方式
 * 阿里热修复 https://emas.console.aliyun.com/?spm=5176.12818093.aliyun_sidebar.115.488716d0rEudZw#/product/3660126/hotfix/25665625/2
 * Sophix入口类，专门用于初始化Sophix，不应包含任何业务逻辑。
 * 此类必须继承自SophixApplication，onCreate方法不需要实现。
 * 此类不应与项目中的其他类有任何互相调用的逻辑，必须完全做到隔离。
 * AndroidManifest中设置application为此类，而SophixEntry中设为原先Application类。
 * 注意原先Application里不需要再重复初始化Sophix，并且需要避免混淆原先Application类。
 * 如有其它自定义改造，请咨询官方后妥善处理。
 */
public class SophixStubApplication extends SophixApplication {
    private static final String TAG = SophixStubApplication.class.getName();
    private static SophixStubApplication instance;

    //构造方法不能私有，否则报错
    public static SophixStubApplication getInstance() {
        return instance;
    }

    // 此处SophixEntry应指定真正的Application，并且保证RealApplicationStubSophixStubApplication不被混淆。
    @Keep
    @SophixEntry(App.class)
    static class RealApplicationStub {
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
//         如果需要使用MultiDex，需要在此处调用。
        MultiDex.install(this);
        initSophix();
        instance = this;
    }

    private void initSophix() {
        String appVersion;
        try {
            appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
        } catch (Exception e) {
            appVersion = "1.0.0";
        }
        Log.e(TAG, "appVersion :" + appVersion);
        SophixManager.getInstance().setContext(this)
                .setAppVersion(appVersion)
                .setAesKey(null)
                .setEnableDebug(true)
                .setEnableFullLog()
                .setPatchLoadStatusStub(patchLoadStatusListener)
                .initialize();
    }

    private PatchLoadStatusListener interceptListener;

    public void queryAndLoadNewPatch() {
        SophixManager.getInstance().queryAndLoadNewPatch();
    }

    public void queryAndLoadNewPatch(PatchLoadStatusListener interceptListener) {
        SophixManager.getInstance().queryAndLoadNewPatch();
        this.interceptListener = interceptListener;
    }

    private PatchLoadStatusListener patchLoadStatusListener = new PatchLoadStatusListener() {
        @Override
        public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
            Log.e(TAG, "SophixUtil onLoad mode:" + mode + ",code:" + code + ",info:" + info + ",handlePatchVersion:" + handlePatchVersion);
            // 补丁加载回调通知
            switch (code) {
                case PatchStatus.CODE_LOAD_SUCCESS: // 表明补丁加载成功
                    Log.e(TAG, "补丁加载成功");

                    break;
                case PatchStatus.CODE_LOAD_RELAUNCH:
//                    SharePreManager.saveHasNewPatch(true);
                    if (interceptListener != null) {
                        interceptListener.onLoad(mode, code, info, handlePatchVersion);
                        return;
                    }
                    // 表明新补丁生效需要重启. 开发者可提示用户或者强制重启;
                    // 建议: 用户可以监听进入后台事件, 然后应用自杀
                    Log.e(TAG, "新补丁生效需要重启");

                    break;
                case PatchStatus.CODE_LOAD_FAIL:
                    // 内部引擎异常, 推荐此时清空本地补丁, 防止失败补丁重复加载
                    Log.e(TAG, "内部引擎异常, 推荐此时清空本地补丁, 防止失败补丁重复加载");
                    break;
                case PatchStatus.CODE_DOWNLOAD_SUCCESS: // 表明补丁下载成功
                    Log.e(TAG, "补丁下载成功");

                    break;
                case PatchStatus.CODE_REQ_NOUPDATE: // 没有检测到更新包
                    Log.e(TAG, "没有检测到更新包");

                    break;
                default: // 其它状态信息, 查看PatchStatus类说明
                    Log.e(TAG, "其它code信息, 查看PatchStatus类说明,code=" + code);

                    break;
            }
        }
    };
}

